#include "Effect.h"

#include "Exceptions.h"

Effect::Effect(unsigned long mgef, const Effect* neg): code(mgef), negative(neg),
															sub("", NULL, subleast),
															lea("", NULL, least),
															les("", NULL, lesser),
															com("", NULL, common),
															grt("", NULL, greater),
															grn("", NULL, grand),
															ult("", NULL, ultra),
															souls(0),
															onSelf(false),
															noVars(true),
															minUses(0),
															maxUses(0),
															noDurChance(1),
															minMagPct(0),
															minDurPct(0),
															rank(0),
															freq(0) {
	sub.mgef = lea.mgef = les.mgef = com.mgef = grt.mgef = grn.mgef = ult.mgef = this;
}

unsigned long Effect::getMGEF() const {
	return code;
}

bool Effect::setMGEF(unsigned long newVal) {
	code = newVal;
	return true;
}

const Effect* Effect::getNegative() const {
	return negative;
}

bool Effect::setNegative(const Effect* newVal) {
	negative = newVal;
	return true;
}

bool Effect::hasAffix(const Soulgem& soulLevel) const {
	return (soulLevel & souls) != 0;
}

string Effect::getAffix(const Soulgem& soulLevel) const {
	if ( com > soulLevel ) {
		if ( sub == soulLevel )
			return sub.get();
		else if ( lea == soulLevel )
			return lea.get();
		else if ( les == soulLevel )
			return les.get();
	}
	else { // if ( com < soulLevel )
		if ( com == soulLevel )
			return com.get();
		else if ( grt == soulLevel )
			return grt.get();
		else if ( grn == soulLevel )
			return grn.get();
		else if ( ult == soulLevel )
			return ult.get();
	}
	throw unknown_soulgem();
}

bool Effect::setAffix(const Soulgem& soulLevel, const string name) {
	if ( com > soulLevel ) {
		if ( sub == soulLevel )
			return sub.set(name);
		else if ( lea == soulLevel )
			return lea.set(name);
		else if ( les == soulLevel )
			return les.set(name);
	}
	else { // if ( com < soulLevel )
		if ( com == soulLevel )
			return com.set(name);
		else if ( grt == soulLevel )
			return grt.set(name);
		else if ( grn == soulLevel )
			return grn.set(name);
		else if ( ult == soulLevel )
			return ult.set(name);
	}
	throw unknown_soulgem();
}

bool Effect::clrAffix(const Soulgem& soulLevel) {
	if ( com > soulLevel ) {
		if ( sub == soulLevel )
			return sub.clr();
		else if ( lea == soulLevel )
			return lea.clr();
		else if ( les == soulLevel )
			return les.clr();
	}
	else { // if ( com < soulLevel )
		if ( com == soulLevel )
			return com.clr();
		else if ( grt == soulLevel )
			return grt.clr();
		else if ( grn == soulLevel )
			return grn.clr();
		else if ( ult == soulLevel )
			return ult.clr();
	}
	throw unknown_soulgem();
}

const Affix& Effect::operator[](const Soulgem& soulLevel) const {
	if ( com > soulLevel ) {
		if ( sub == soulLevel )
			return sub;
		else if ( lea == soulLevel )
			return lea;
		else if ( les == soulLevel )
			return les;
	}
	else { // if ( com < soulLevel )
		if ( com == soulLevel )
			return com;
		else if ( grt == soulLevel )
			return grt;
		else if ( grn == soulLevel )
			return grn;
		else if ( ult == soulLevel )
			return ult;
	}
	throw unknown_soulgem();
}

Affix& Effect::operator[](const Soulgem& soulLevel) {
	if ( com > soulLevel ) {
		if ( sub == soulLevel )
			return sub;
		else if ( lea == soulLevel )
			return lea;
		else if ( les == soulLevel )
			return les;
	}
	else { // if ( com < soulLevel )
		if ( com == soulLevel )
			return com;
		else if ( grt == soulLevel )
			return grt;
		else if ( grn == soulLevel )
			return grn;
		else if ( ult == soulLevel )
			return ult;
	}
	throw unknown_soulgem();
}

bool Effect::hasAffixes(const unsigned int bitmap) const {
	return (souls & bitmap) == bitmap;
}

bool Effect::getOnSelf() const {
	return onSelf;
}

bool Effect::setOnSelf(const bool newVal) {
	onSelf = newVal;
	return true;
}

bool Effect::getNoVars() const {
	return noVars;
}

bool Effect::setNoVars(const bool newVal) {
	noVars = newVal;
	return true;
}

unsigned int Effect::getMinUses() const {
	return minUses;
}

bool Effect::setMinUses(const unsigned int newVal) {
	minUses = newVal;
	return true;
}

unsigned int Effect::getMaxUses() const {
	return maxUses;
}

bool Effect::setMaxUses(const unsigned int newVal) {
	maxUses = newVal;
	return true;
}

float Effect::getNoDurChance() const {
	return noDurChance;
}

bool Effect::setNoDurChance(const float newVal) {
	noDurChance = newVal;
	return true;
}

float Effect::getMinMagPct() const {
	return minMagPct;
}

bool Effect::setMinMagPct(const float newVal) {
	minMagPct = newVal;
	return true;
}

float Effect::getMinDurPct() const {
	return minDurPct;
}

bool Effect::setMinDurPct(const float newVal) {
	minDurPct = newVal;
	return true;
}

float Effect::getRank() const {
	return rank;
}

bool Effect::setRank(const float newVal) {
	rank = newVal;
	return true;
}

float Effect::getFreq() const {
	return freq;
}

bool Effect::setFreq(const float newVal) {
	freq = newVal;
	return true;
}
